﻿using Common;
using System.Collections.Concurrent;
using System.IO.Ports;

namespace NewDevice.RS485
{
    /// <summary>
    /// 8通道电阻测量模块
    /// </summary>
    [Obsolete("请使用ZhT08R14N1_V2")]
    public class ZhT08R14N1
    {
        #region 初始化设置指令

        //01 06 00 51 00 00 //设置波特率115200
        //01 06 01 FB 00 10 //主动上传使能
        //01 06 01 FC 06 00 //RS485 接口主动上传类型选择
        //阻值=读值/100

        #endregion 初始化设置指令

        private readonly SerialPort _serialPort; // 串口对象
        private readonly ConcurrentQueue<byte[]?> _dataQueue = new ConcurrentQueue<byte[]?>(); // 接收数据队列
        private readonly Dictionary<int, List<short>?> _registerValues = new Dictionary<int, List<short>?>(); // 缓存寄存器历史值
        private DateTime _lastDataReceivedTime = DateTime.MinValue; // 上次接收到数据的时间
        private const int TimeoutSeconds = 5; // 超时时间（秒）
        private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();

        // 锁对象，用于保护 _registerValues
        private readonly Lock _lock = new Lock();

        /// <summary>
        /// 事件：用于通知通信异常
        /// </summary>
        public event Action<string> OnCommunicationError = null!;

        /// <summary>
        /// 可配置的属性：每个寄存器的历史值列表的最大长度
        /// </summary>
        public int MaxHistorySize { get; set; } = 5000; // 默认值为 5000

        /// <summary>
        /// 构造函数，允许传入串口名称和波特率
        /// </summary>
        /// <param name="portName"></param>
        /// <param name="baudRate"></param>
        public ZhT08R14N1(string portName = "COM7", int baudRate = 115200)
        {
            _serialPort = new SerialPort(portName, baudRate);
        }

        /// <summary>
        /// 属性：外部可访问的寄存器历史值
        /// </summary>
        public Dictionary<int, List<double>> RegisterValues
        {
            get
            {
                lock (_lock)
                {
                    // 返回 _registerValues 的深拷贝，并对所有值处理后，保留三位小数
                    return _registerValues.ToDictionary(
                        kvp => kvp.Key, // 键是 int，直接复制
                        kvp => kvp!.Value!.Select(v => Math.Round(v / 100.0, 3)).ToList() // 对 List<Int16> 中的每个值除以 1000，并保留三位小数
                    );
                }
            }
        }

        public void Open()
        {
            // 注册串口数据接收事件
            _serialPort.DataReceived += SerialPort_DataReceived;

            MyLog.Debug($"Opening serial port {_serialPort.PortName} at {_serialPort.BaudRate} baud...");
            _serialPort.Open();
            MyLog.Debug("Serial port opened.");

            // 启动数据处理任务
            var processTask = Task.Run(() => ProcessDataAsync(_cancellationTokenSource.Token));

            // 启动超时检测任务
            var timeoutTask = Task.Run(() => CheckForTimeoutAsync(_cancellationTokenSource.Token));
        }

        private byte[] _remainingData = []; // 用于缓存不足一组的数据

        // 串口数据接收事件处理
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                int bytesToRead = _serialPort.BytesToRead;
                byte[] buffer = new byte[bytesToRead];
                _serialPort.Read(buffer, 0, bytesToRead);

                // 将接收到的数据与剩余数据拼接
                byte[] combinedData = new byte[_remainingData.Length + bytesToRead];
                Buffer.BlockCopy(_remainingData, 0, combinedData, 0, _remainingData.Length);
                Buffer.BlockCopy(buffer, 0, combinedData, _remainingData.Length, bytesToRead);

                // 处理完整的数据包
                int offset = 0;
                while (offset + 21 <= combinedData.Length) // 每组数据长度为 21 字节
                {
                    // 检查数据格式是否正确
                    if (combinedData[offset] == 0x01 && combinedData[offset + 1] == 0x03 && combinedData[offset + 2] == 0x10)
                    {
                        // 提取一组完整的数据（21 字节）
                        byte[]? dataPacket = new byte[21];
                        Buffer.BlockCopy(combinedData, offset, dataPacket, 0, 21);

                        // 将数据包加入队列
                        _dataQueue.Enqueue(dataPacket);

                        // 更新偏移量
                        offset += 21;
                    }
                    else
                    {
                        // 数据格式错误，跳过 1 字节继续检查
                        offset++;
                    }
                }

                // 缓存不足一组的数据
                _remainingData = new byte[combinedData.Length - offset];
                Buffer.BlockCopy(combinedData, offset, _remainingData, 0, _remainingData.Length);

                // 更新上次接收到数据的时间
                _lastDataReceivedTime = DateTime.Now;
            }
            catch (Exception ex)
            {
                MyLog.Debug($"Error receiving data: {ex.Message}");
                OnCommunicationError?.Invoke($"Error receiving data: {ex.Message}");
            }
        }

        // 处理数据任务
        private async Task ProcessDataAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    if (_dataQueue.TryDequeue(out byte[]? data))
                    {
                        // 解析数据并更新寄存器值
                        ParseReceivedData(data);
                    }
                    else
                    {
                        await Task.Delay(10, cancellationToken); // 队列为空时稍作等待
                    }
                }
                catch (Exception ex)
                {
                    MyLog.Debug($"Error processing data: {ex.Message}");
                    OnCommunicationError?.Invoke($"Error processing data: {ex.Message}");
                }
            }
        }

        // 超时检测任务
        private async Task CheckForTimeoutAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(1000, cancellationToken); // 每秒检查一次

                if ((DateTime.Now - _lastDataReceivedTime).TotalSeconds > TimeoutSeconds)
                {
                    OnCommunicationError?.Invoke("No data received for a long time. Communication may be interrupted.");
                    _lastDataReceivedTime = DateTime.Now; // 重置时间，避免重复通知
                }
            }
        }

        // 解析接收到的数据
        private void ParseReceivedData(byte[]? data)
        {
            lock (_lock)
            {
                // 检查是否有足够的数据进行解析
                if (data!.Length < 5) // 至少需要地址、操作码、数据长度
                {
                    return;
                }

                // 解析数据
                byte address = data[0];       // 地址
                byte opCode = data[1];        // 操作码
                byte dataLength = data[2];    // 数据长度

                // 检查是否接收到了完整的数据包
                if (data.Length < 3 + dataLength + 2) // 3（地址+操作码+长度） + 数据长度 + 2（校验码）
                {
                    return;
                }

                // 提取数据部分
                byte[] registerData = new byte[dataLength];
                Array.Copy(data, 3, registerData, 0, dataLength);

                // 提取校验码
                byte[] checksum = new byte[2];
                Array.Copy(data, 3 + dataLength, checksum, 0, 2);

                // 打印解析结果
                //Console.WriteLine($"Parsed Data - Address: {address:X2}, OpCode: {opCode:X2}, DataLength: {dataLength}, Data: {BitConverter.ToString(registerData)}, Checksum: {BitConverter.ToString(checksum)}");

                // 解析寄存器值
                ParseRegisterValues(registerData);
            }
        }

        // 解析寄存器值并更新缓存
        private void ParseRegisterValues(byte[] data)
        {
            lock (_lock)
            {
                // 每 2 个字节代表一个寄存器的值
                for (int i = 0; i < data.Length; i += 2)
                {
                    if (i + 1 >= data.Length) // 确保有足够的数据
                    {
                        break;
                    }

                    // 寄存器地址（假设从 0 开始递增）
                    int registerAddress = i / 2;

                    // 寄存器值（16 位，大端序）
                    Int16 registerValue = (Int16)((data[i] << 8) | data[i + 1]);

                    // 初始化寄存器的历史值列表（如果不存在）
                    if (!_registerValues.ContainsKey(registerAddress))
                    {
                        _registerValues[registerAddress] = new List<Int16>();
                    }

                    // 如果历史值列表超过 1000 条，移除最早的数据
                    var registerHistory = _registerValues[registerAddress];
                    registerHistory!.Add(registerValue);
                    if (registerHistory.Count > MaxHistorySize)
                    {
                        registerHistory.RemoveAt(0);
                        //Console.WriteLine($"Register {registerAddress} changed to {registerValue}. History: {string.Join(", ", _registerValues[registerAddress])}");
                    }
                }
            }
        }

        /// <summary>
        /// 获取指定寄存器的当前值
        /// </summary>
        /// <param name="registerAddress"></param>
        /// <returns></returns>
        public Int16 GetRegisterValue(int registerAddress)
        {
            lock (_lock)
            {
                if (_registerValues.TryGetValue(registerAddress, out List<short>? values) && values!.Count! > 0)
                {
                    return values.Last(); // 返回最新的值
                }
                else
                {
                    MyLog.Debug($"Register {registerAddress} not found. Returning default value 0.");
                    return 0; // 返回默认值
                }
            }
        }

        /// <summary>
        /// 获取指定寄存器的所有历史值
        /// </summary>
        /// <param name="registerAddress"></param>
        /// <returns></returns>
        public List<Int16> GetRegisterHistory(int registerAddress)
        {
            lock (_lock)
            {
                if (_registerValues.TryGetValue(registerAddress, out List<short>? values))
                {
                    return values!.ToList(); // 返回副本
                }
                else
                {
                    MyLog.Debug($"Register {registerAddress} not found. Returning empty list.");
                    return new List<Int16>();
                }
            }
        }

        /// <summary>
        /// 清空寄存器值缓存
        /// </summary>
        public void ClearRegisterValues()
        {
            lock (_lock)
            {
                foreach (var item in _registerValues)
                {
                    item.Value?.Clear();
                }
                //_registerValues.Clear();
                MyLog.Debug("Register values cache cleared.");
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        public void Disconnect()
        {
            _cancellationTokenSource.Cancel();
            _serialPort?.Close();
            MyLog.Debug("Serial port closed.");
        }
    }
}